eval_ and function prototype declaration

Hi !

 

I know that it is not possible to include in a DOORS startup process a DXL file that contains function prototype declaration. Example:

void func(string);

It makes me crazy but I can live with that...

But it seems that the eval_ function have this limitation as well.

My question is :

Is it possible to evaluate a DXL Code that contains (i.e. includes a DXL file that contains) prototypes declarations ?


jaracic - Mon Nov 23 10:27:33 EST 2015

Re: eval_ and function prototype declaration
Mathias Mamsch - Mon Nov 23 15:50:26 EST 2015

Without trying I highly doubt that. The startup DXL files are not parsed differently from normal DXL files - with some minor differences, that can usually be overcome by wrapping the code block inside curly braces.

{
     ....
}

Still in DXL there is an alternative to forward declarations. When used on classes, I call them "virtual functions", the idea is store the address of a function inside a variable at runtime.

// ***************** Virtual function declaration, put this at startup **********************
int funcAd = 0; // here we store the address of the function 

// this function is for being able to call the stored function with its parameters
string callProxy (string func(string, string), string par1, string par2) {
    return func(par1, par2); 
}

// this is the virtual function. It uses our proxy for calling the stored function. 
string virtual_function (string par1, string par2) {
    if (funcAd == 0) return ""; 
    return callProxy( addr_ funcAd, par1, par2); 
}

// this function allows us to set the virtual function to call
void set_virtual_function(string func(string, string)) { funcAd = ((addr_ func) int); }

// This library function uses the virtual function, although the real code has not been declared yet. 
void library_function () {
       virtual_function ("A", "B"); // call the function that is not yet defined
}

// ***** later in the code you define the function (like with forward declararations) *****

// This is the function we "forward declared" ... 
string my_function (string p1, string p2) {
    print "P1: " p1 " P2: " p2 "\n";
}

set_virtual_function (my_function); // set your function as the one to be called.

library_function () // call the library function ... it will call my_function, although it was defined later. 

(I did not test the code for typos). Maybe this gives you an alternative way of doing what you want to do. What is it by the way, that you want to do? Regards, Mathias

Re: eval_ and function prototype declaration
jaracic - Wed Nov 25 05:38:11 EST 2015

Mathias Mamsch - Mon Nov 23 15:50:26 EST 2015

Without trying I highly doubt that. The startup DXL files are not parsed differently from normal DXL files - with some minor differences, that can usually be overcome by wrapping the code block inside curly braces.

{
     ....
}

Still in DXL there is an alternative to forward declarations. When used on classes, I call them "virtual functions", the idea is store the address of a function inside a variable at runtime.

// ***************** Virtual function declaration, put this at startup **********************
int funcAd = 0; // here we store the address of the function 

// this function is for being able to call the stored function with its parameters
string callProxy (string func(string, string), string par1, string par2) {
    return func(par1, par2); 
}

// this is the virtual function. It uses our proxy for calling the stored function. 
string virtual_function (string par1, string par2) {
    if (funcAd == 0) return ""; 
    return callProxy( addr_ funcAd, par1, par2); 
}

// this function allows us to set the virtual function to call
void set_virtual_function(string func(string, string)) { funcAd = ((addr_ func) int); }

// This library function uses the virtual function, although the real code has not been declared yet. 
void library_function () {
       virtual_function ("A", "B"); // call the function that is not yet defined
}

// ***** later in the code you define the function (like with forward declararations) *****

// This is the function we "forward declared" ... 
string my_function (string p1, string p2) {
    print "P1: " p1 " P2: " p2 "\n";
}

set_virtual_function (my_function); // set your function as the one to be called.

library_function () // call the library function ... it will call my_function, although it was defined later. 

(I did not test the code for typos). Maybe this gives you an alternative way of doing what you want to do. What is it by the way, that you want to do? Regards, Mathias

Thanks Mathias for your virtual function solution, and for sure I'll use it in many situations that justify it...

I developed a first version of DXL library for testLink; for that I had to use sometimes forward declarations because involved classes (struct) are quit "innermost" by design, and introducing the virtual function technique only to make the library "loadable" in the DOORS startup (or in an eval_) makes me.... angry. 

It is why I made some additionnal tests:

the following code works:

                Buffer dxlCodeBuf = create()
                dxlCodeBuf += ("void fun1(string);\n")
                dxlCodeBuf += ("void fun2(){fun1(\"Hi=\")}\n")
                dxlCodeBuf += ("void fun1(string msg){print msg}\n")
                dxlCodeBuf += ("fun2()\n")    
                string errmsg = eval_(stringOf(dxlCodeBuf))
                
                delete dxlCodeBuf

It means that the problem was not where I thought.

I also isolated better my test of forward declaration in startup.inc and it works.

Sorry for the annoyance ! and once again thanks for the virtual function tip

Re: eval_ and function prototype declaration
jaracic - Wed Nov 25 06:02:10 EST 2015

jaracic - Wed Nov 25 05:38:11 EST 2015

Thanks Mathias for your virtual function solution, and for sure I'll use it in many situations that justify it...

I developed a first version of DXL library for testLink; for that I had to use sometimes forward declarations because involved classes (struct) are quit "innermost" by design, and introducing the virtual function technique only to make the library "loadable" in the DOORS startup (or in an eval_) makes me.... angry. 

It is why I made some additionnal tests:

the following code works:

                Buffer dxlCodeBuf = create()
                dxlCodeBuf += ("void fun1(string);\n")
                dxlCodeBuf += ("void fun2(){fun1(\"Hi=\")}\n")
                dxlCodeBuf += ("void fun1(string msg){print msg}\n")
                dxlCodeBuf += ("fun2()\n")    
                string errmsg = eval_(stringOf(dxlCodeBuf))
                
                delete dxlCodeBuf

It means that the problem was not where I thought.

I also isolated better my test of forward declaration in startup.inc and it works.

Sorry for the annoyance ! and once again thanks for the virtual function tip

I also isolated better my test of forward declaration in startup.inc and it works.

Actually I did not say that forward declaration works in startup (they are not resolved!)

Re: eval_ and function prototype declaration
rboissel - Fri Feb 03 03:32:41 EST 2017

Mathias Mamsch - Mon Nov 23 15:50:26 EST 2015

Without trying I highly doubt that. The startup DXL files are not parsed differently from normal DXL files - with some minor differences, that can usually be overcome by wrapping the code block inside curly braces.

{
     ....
}

Still in DXL there is an alternative to forward declarations. When used on classes, I call them "virtual functions", the idea is store the address of a function inside a variable at runtime.

// ***************** Virtual function declaration, put this at startup **********************
int funcAd = 0; // here we store the address of the function 

// this function is for being able to call the stored function with its parameters
string callProxy (string func(string, string), string par1, string par2) {
    return func(par1, par2); 
}

// this is the virtual function. It uses our proxy for calling the stored function. 
string virtual_function (string par1, string par2) {
    if (funcAd == 0) return ""; 
    return callProxy( addr_ funcAd, par1, par2); 
}

// this function allows us to set the virtual function to call
void set_virtual_function(string func(string, string)) { funcAd = ((addr_ func) int); }

// This library function uses the virtual function, although the real code has not been declared yet. 
void library_function () {
       virtual_function ("A", "B"); // call the function that is not yet defined
}

// ***** later in the code you define the function (like with forward declararations) *****

// This is the function we "forward declared" ... 
string my_function (string p1, string p2) {
    print "P1: " p1 " P2: " p2 "\n";
}

set_virtual_function (my_function); // set your function as the one to be called.

library_function () // call the library function ... it will call my_function, although it was defined later. 

(I did not test the code for typos). Maybe this gives you an alternative way of doing what you want to do. What is it by the way, that you want to do? Regards, Mathias

Hi Mathias,

I just started to use your smart virtual function system to workaround the forward declaration problem in batch mode.

But after having patched doors to the version 9.6.1.7 64bits, I have the following warning :

"64 bits value affected to a 32 bits int value".

Ok, I understand that after migration pointers move to 64 bits format and int stay in 32 bits so it could not match.

But is there a solution ?

It seems to work but I'm afraid about a pitfal.

Thank you

robert

Re: eval_ and function prototype declaration
Mathias Mamsch - Fri Feb 03 04:23:16 EST 2017

rboissel - Fri Feb 03 03:32:41 EST 2017

Hi Mathias,

I just started to use your smart virtual function system to workaround the forward declaration problem in batch mode.

But after having patched doors to the version 9.6.1.7 64bits, I have the following warning :

"64 bits value affected to a 32 bits int value".

Ok, I understand that after migration pointers move to 64 bits format and int stay in 32 bits so it could not match.

But is there a solution ?

It seems to work but I'm afraid about a pitfal.

Thank you

robert

Which exact DOORS version are you using? 9.6.1.7? Are there different patch levels for that release?

And does this problem only occur in batch mode? 

I can run the above code in interactive mode on DOORS 9.6.1.7 without a warning. Can you post the exact code you are running? 

Note: You can get around the warning by using "noError() ... lastError()" ...

Regards, Mathias

Re: eval_ and function prototype declaration
rboissel - Fri Feb 03 04:44:39 EST 2017

Mathias Mamsch - Fri Feb 03 04:23:16 EST 2017

Which exact DOORS version are you using? 9.6.1.7? Are there different patch levels for that release?

And does this problem only occur in batch mode? 

I can run the above code in interactive mode on DOORS 9.6.1.7 without a warning. Can you post the exact code you are running? 

Note: You can get around the warning by using "noError() ... lastError()" ...

Regards, Mathias

The client version is 9.6.1.7 build 96622, it's a french version.

For test I take your example (above). 

The problem occurs in batch mode and in the interactive editor.

Thank you for your attention

Regards

Robert

 

Re: eval_ and function prototype declaration
Mathias Mamsch - Fri Feb 03 06:08:48 EST 2017

rboissel - Fri Feb 03 04:44:39 EST 2017

The client version is 9.6.1.7 build 96622, it's a french version.

For test I take your example (above). 

The problem occurs in batch mode and in the interactive editor.

Thank you for your attention

Regards

Robert

 

Just to be clear - Running this exact code under DOORS 9.6.1.7, 64 Bit, Build 96622, after starting in interactive mode, using Tools / Edit DXL, from the DXL interaction window gives you a warning? 

lastError(); lastError(); lastError() // to be sure

// ***************** Virtual function declaration, put this at startup **********************
int funcAd = 0; // here we store the address of the function 

// this function is for being able to call the stored function with its parameters
string callProxy (string func(string, string), string par1, string par2) {
    return func(par1, par2); 
}

// this is the virtual function. It uses our proxy for calling the stored function. 
string virtual_function (string par1, string par2) {
    if (funcAd == 0) return ""; 
    return callProxy( addr_ funcAd, par1, par2); 
}

// this function allows us to set the virtual function to call
void set_virtual_function(string func(string, string)) { funcAd = ((addr_ func) int); }

// This library function uses the virtual function, although the real code has not been declared yet. 
void library_function () {
       virtual_function ("A", "B"); // call the function that is not yet defined
}

// ***** later in the code you define the function (like with forward declararations) *****

// This is the function we "forward declared" ... 
string my_function (string p1, string p2) {
    print "P1: " p1 " P2: " p2 "\n";
    return "X"; 
}

set_virtual_function (my_function); // set your function as the one to be called.

library_function () // call the library function ... it will call my_function, although it was defined later. 

For me there is no warning on the same build. Please post the exact filesize of your doors.exe (and an MD5 maybe :-)) to be sure. 

Regards, Mathias

Re: eval_ and function prototype declaration
rboissel - Fri Feb 03 08:45:23 EST 2017

Mathias Mamsch - Fri Feb 03 06:08:48 EST 2017

Just to be clear - Running this exact code under DOORS 9.6.1.7, 64 Bit, Build 96622, after starting in interactive mode, using Tools / Edit DXL, from the DXL interaction window gives you a warning? 

lastError(); lastError(); lastError() // to be sure

// ***************** Virtual function declaration, put this at startup **********************
int funcAd = 0; // here we store the address of the function 

// this function is for being able to call the stored function with its parameters
string callProxy (string func(string, string), string par1, string par2) {
    return func(par1, par2); 
}

// this is the virtual function. It uses our proxy for calling the stored function. 
string virtual_function (string par1, string par2) {
    if (funcAd == 0) return ""; 
    return callProxy( addr_ funcAd, par1, par2); 
}

// this function allows us to set the virtual function to call
void set_virtual_function(string func(string, string)) { funcAd = ((addr_ func) int); }

// This library function uses the virtual function, although the real code has not been declared yet. 
void library_function () {
       virtual_function ("A", "B"); // call the function that is not yet defined
}

// ***** later in the code you define the function (like with forward declararations) *****

// This is the function we "forward declared" ... 
string my_function (string p1, string p2) {
    print "P1: " p1 " P2: " p2 "\n";
    return "X"; 
}

set_virtual_function (my_function); // set your function as the one to be called.

library_function () // call the library function ... it will call my_function, although it was defined later. 

For me there is no warning on the same build. Please post the exact filesize of your doors.exe (and an MD5 maybe :-)) to be sure. 

Regards, Mathias

Exactly.

The md5sum :

>>>>>>>>>>>>>> 

C:\Program Files\IBM\Rational\DOORS\9.6\bin>C:\Tools\md5sums.exe doors.exe

MD5sums 1.2 freeware for Win9x/ME/NT/2000/XP+
Copyright (C) 2001-2005 Jem Berkes -
http://www.pc-tools.net/
Type C:\Tools\md5sums.exe -h for help

[Path] / filename                              MD5 sum
-------------------------------------------------------------------------------
[C:\Program Files\IBM\Rational\DOORS\9.6\bin\]
doors.exe                                      317c5084940333446b8fbbe276c218ff

<<<<<<<<<<<<<<<<<<<<<<<<< 

The binary size : 06/12/2016  17:05        57 392 648 doors.exe

In file attachment you will find the screen shot of the interactive editor.


Attachments

doors.png

Re: eval_ and function prototype declaration
Mathias Mamsch - Fri Feb 03 08:58:43 EST 2017

rboissel - Fri Feb 03 08:45:23 EST 2017

Exactly.

The md5sum :

>>>>>>>>>>>>>> 

C:\Program Files\IBM\Rational\DOORS\9.6\bin>C:\Tools\md5sums.exe doors.exe

MD5sums 1.2 freeware for Win9x/ME/NT/2000/XP+
Copyright (C) 2001-2005 Jem Berkes -
http://www.pc-tools.net/
Type C:\Tools\md5sums.exe -h for help

[Path] / filename                              MD5 sum
-------------------------------------------------------------------------------
[C:\Program Files\IBM\Rational\DOORS\9.6\bin\]
doors.exe                                      317c5084940333446b8fbbe276c218ff

<<<<<<<<<<<<<<<<<<<<<<<<< 

The binary size : 06/12/2016  17:05        57 392 648 doors.exe

In file attachment you will find the screen shot of the interactive editor.

Same DOORS. Different results. Thats a new one. :-\

Ok, anyway, did you try simply wrapping in noError, lastError? This should make the warning go away: 

void set_virtual_function(string func(string, string)) { noError(); funcAd = ((addr_ func) int); lastError(); }

Regards, Mathias

Re: eval_ and function prototype declaration
rboissel - Fri Feb 03 09:26:13 EST 2017

Mathias Mamsch - Fri Feb 03 08:58:43 EST 2017

Same DOORS. Different results. Thats a new one. :-\

Ok, anyway, did you try simply wrapping in noError, lastError? This should make the warning go away: 

void set_virtual_function(string func(string, string)) { noError(); funcAd = ((addr_ func) int); lastError(); }

Regards, Mathias

Yes it did

Re: eval_ and function prototype declaration
rboissel - Mon Feb 06 04:05:12 EST 2017

Mathias Mamsch - Fri Feb 03 08:58:43 EST 2017

Same DOORS. Different results. Thats a new one. :-\

Ok, anyway, did you try simply wrapping in noError, lastError? This should make the warning go away: 

void set_virtual_function(string func(string, string)) { noError(); funcAd = ((addr_ func) int); lastError(); }

Regards, Mathias

Hi Mathias,

don't you think hiding this waning could hide a problem later ?

Regards

Robert

Re: eval_ and function prototype declaration
Mathias Mamsch - Mon Feb 06 04:39:20 EST 2017

rboissel - Mon Feb 06 04:05:12 EST 2017

Hi Mathias,

don't you think hiding this waning could hide a problem later ?

Regards

Robert

I guess it depends on how often IBM plans to change the internals of their integer arithmetics (hopefully not any more). If you want to develop for DOORS 64 9.6.1.7 and upwards you should consider to use the new Addr64_ type instead of an integer. But weirdly I found, that this type will also produce a warning, even though it is considered to hold a 64 bit value. Therefore I would not give to much about the warning for now. But in the end.

You never know ;-) In the worst case IBM will "fix" the assignment of 64 bit values to integers, clipping to 32 bit. It should be easily possible to test that. Regards, Mathias

 

Re: eval_ and function prototype declaration
rboissel - Mon Feb 06 04:42:29 EST 2017

Mathias Mamsch - Mon Feb 06 04:39:20 EST 2017

I guess it depends on how often IBM plans to change the internals of their integer arithmetics (hopefully not any more). If you want to develop for DOORS 64 9.6.1.7 and upwards you should consider to use the new Addr64_ type instead of an integer. But weirdly I found, that this type will also produce a warning, even though it is considered to hold a 64 bit value. Therefore I would not give to much about the warning for now. But in the end.

You never know ;-) In the worst case IBM will "fix" the assignment of 64 bit values to integers, clipping to 32 bit. It should be easily possible to test that. Regards, Mathias

 

Thank you very much for your help.

Robert